package mc.support.web.action.invoke;

import mc.support.web.action.WriteException;

import javax.servlet.http.HttpServletResponse;
import java.io.*;

/**
 * Created with IntelliJ IDEA. <br/>
 * Author: Francis Yun    <br/>
 * Date: 2014-04-21  <br/>
 */
public enum ResultWriter {

    text,
    binary;

    private static final String TEXT = "text/plain";
    private static final String BINARY = "application/octet-stream";

    private static int bufferSize = 4 * 1024;

    public static int getBufferSize() {
        return bufferSize;
    }

    public static void setBufferSize(int bufferSize) {
        ResultWriter.bufferSize = bufferSize;
    }

    public void writeResult(ResultWriter writer, HttpServletResponse resp, Object result) throws WriteException {
        PrintWriter printWriter = null;
        OutputStream outputStream = null;
        try {
            if ( text == writer ) {
                resp.setContentType( TEXT );
                printWriter = resp.getWriter();
                writeString(result, printWriter );
            } else if ( binary == writer ) {
                resp.setContentType( BINARY );
                outputStream = resp.getOutputStream();
                writeBinary(result, outputStream );
            }
        } catch (IOException e) {
            throw new WriteException( printWriter, outputStream, e );
        }
    }

    private void writeString(Object result, PrintWriter writer) throws IOException {
        writer.print( null != result ? result.toString() : "" );
        writer.flush();
    }

    private void writeBinary(Object result, OutputStream out) throws IOException {
        result = null != result ? result : "";
        InputStream in;
        if ( result instanceof InputStream ) {
            in = (InputStream) result;
        } else {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject( result );

            oos.flush();
            oos.close();

            in = new ByteArrayInputStream( baos.toByteArray() );
        }

        byte[] buffer = new byte[ bufferSize ];
        int length;
        while ( (length = in.read(buffer)) > 0 ){
            out.write(buffer, 0, length);
        }
        in.close();
        out.flush();
    }

}
